#include <Misc.au3>
#include <ScreenCapture.au3>
#include <..\utility.au3>

HotKeySet("{PAUSE}", "theExit")
$runs = 0
$deaths = 0
$demonicessence = 1 ; SET THIS TO 0 IF YOU DON'T WANT THE BOT TO PICK UP DEMONIC ESSENCES

call("screenshot", "start")

While 1
	processkey('70', "mousePos") ;F1
	processkey('71', "leorics") ;F2
	processkey('72', "getLegendaries") ;F3
	processkey('73', "repair") ;F4
	processkey('74', "findring") ;F5
	processkey('75', "findcolor") ;F6
	processkey('76', "checkdead") ;F7
	processkey('77', "castSpelltest") ;F8
WEnd

Func leorics()
While 1
	;Log Run Start
	call("logmessage", "Starting Run " & $runs)
	$runs = $runs + 1

	;Randomly take a break
	If $runs > 10 Then
		call("takebreak")
	EndIf

	;Repair if needed
	call("repair")

	;Move to portal
	call("fuzzyclick","left", 101, 33)
	call("fuzzysleep",Random(400,500,1))
	Send("1")
	call("fuzzysleep",Random(400,500,1))
	Send("3")
	call("fuzzysleep",Random(400,500,1))
	Send("4")
	call("fuzzysleep",4000)

	;Teleport to the right
	call("fuzzyclick","left", 1919,200)

	Opt("SendKeyDownDelay", 1200)  ;5 second delay
	Send("2")
	Opt("SendKeyDownDelay", 50)  ;reset to default when done

	;Click shrine
	call("fuzzyclick","left", 1790, 328)
	call("fuzzysleep",Random(2400,3000,1))

	;Fire right
	call("fuzzymove", 1790,328)
	MouseDown("right")
	call("fuzzysleep",Random(2000,2600,1))
	;Explosion
	Send("1")
	call("fuzzymove", 1900, 500)
	call("fuzzysleep",Random(2000,2600,1))

	;If we don't have our stack
	If PixelGetColor(837,920)  <> 0xAD8930 AND PixelGetColor(888,927) <> 0xF6E051 Then
		call("fuzzymove", 1790, 350)
		call("fuzzysleep",Random(2000,2600,1))
		call("fuzzymove", 1900, 550)
		call("fuzzysleep",Random(2000,2600,1))
	EndIf



	;If we don't have our stack
	If PixelGetColor(837,920)  <> 0xAD8930 AND PixelGetColor(888,927) <> 0xF6E051 Then
		;Fire at remaining guys
		Local $finalmobs = PixelSearch(400,300,1920,700,0xF70000,10)
		if IsArray($finalmobs) Then
			call("fuzzymove", $finalmobs[0],$finalmobs[1]+20)
			call("fuzzysleep",Random(600,800,1))
			If Random(1,2,1) = 1 Then
				Send("1")
			EndIf
		EndIf

		$finalmobs = PixelSearch(400,300,1920,700,0xF70000,10)
		if IsArray($finalmobs) Then
			call("fuzzymove", $finalmobs[0],$finalmobs[1]+20)
			call("fuzzysleep",Random(600,800,1))
			If Random(1,2,1) = 1 Then
				Send("1")
			EndIf
		EndIf
	EndIf

	MouseUp("right")
	call("fuzzysleep",Random(200,600,1))

	;Move right
	Send("{CTRLDOWN}")
	call("fuzzyclick", "left", 1280, 450)
	call("fuzzysleep", Random(400,800,1))
	Send("{CTRLUP}")

	;Check to see if we have our stack
	;837, 920, 0xAD8930
	If PixelGetColor(837,920)  <> 0xAD8930 AND PixelGetColor(888,927) <> 0xF6E051 Then
		;Fire right
		call("fuzzymove", 1790,328)
		MouseDown("right")
		call("fuzzysleep",Random(2000,2600,1))
		;Explosion
		Send("1")
		call("fuzzymove", 1900, 500)
		call("fuzzysleep",Random(2000,2600,1))
		MouseUp("right")
	EndIf

	;Check if we are dead and just exit
	If call("checkdead", 0) = 1 Then
		call("fuzzyclick", "left", 0, 0)
		call("fuzzysleep", Random(500,1000))
		call("exitgame", 0)
		ContinueLoop
	EndIf

	;Check to see if we have our stack
	;837, 920, 0xAD8930
	If PixelGetColor(837,920)  <> 0xAD8930 AND PixelGetColor(888,927) <> 0xF6E051 Then
		;Fire right
		call("fuzzymove", 0,328)
		MouseDown("right")
		call("fuzzysleep",Random(2000,2600,1))
		;Explosion
		Send("1")
		call("fuzzymove", 0, 500)
		call("fuzzysleep",Random(2000,2600,1))
		MouseUp("right")
	EndIf

	;Pick up Legendaries
	call("getLegendaries", 0)

	;Check if we are dead and just exit
	If call("checkdead", 0) = 1 Then
		call("fuzzyclick", "left", 0, 0)
		call("fuzzysleep", Random(500,1000))
		call("exitgame", 0)
		ContinueLoop
	EndIf

	;Pick up rare rings
	If call("findring") = 1 Then
		call("fuzzysleep",1000)
		If call("findring") = 1 Then
			call("fuzzysleep",1000)
		EndIf
	EndIf

	;Pick up gold
	;Move right
	Send("{CTRLDOWN}")
	call("fuzzyclick", "left", 1280, 450)
	call("fuzzysleep", Random(400,1000,1))
	Send("{CTRLUP}")

	call("exitgame")

	;Restart Script
WEnd

EndFunc


Func exitgame($checkdead = 1)
	;Exit Game
	Send("{ESC}")
	call("fuzzysleep",50)
	call("fuzzyclick","left", Random(920,925,1), Random(579,585,1))


	call("fuzzymove", Random(0,1920,1), Random(0,1080,1))
	call("fuzzysleep",1000)
	call("fuzzymove", Random(0,1920,1), Random(0,1080,1))
	call("fuzzysleep",1000)
	call("fuzzymove", Random(0,1920,1), Random(0,1080,1))
	call("fuzzysleep",1000)
	call("fuzzymove", Random(0,1920,1), Random(0,1080,1))
	call("fuzzysleep",1000)
	call("fuzzymove", Random(0,1920,1), Random(0,1080,1))
	call("fuzzysleep",1000)
	call("fuzzymove", Random(0,1920,1), Random(0,1080,1))
	call("fuzzysleep",1000)
	call("fuzzymove", Random(0,1920,1), Random(0,1080,1))
	call("fuzzysleep",1000)

	;Check if we are dead
	call("checkdead")

	call("fuzzymove", Random(0,1920,1), Random(0,1080,1))
	call("fuzzysleep",1000)
	call("fuzzymove", Random(0,1920,1), Random(0,1080,1))
	call("fuzzysleep",1000)
	call("fuzzymove", Random(0,1920,1), Random(0,1080,1))
	call("fuzzysleep",1000)
	call("fuzzymove", Random(0,1920,1), Random(0,1080,1))
	call("fuzzysleep",Random(0,1000,1))
	;call("fuzzymove", Random(0,1920,1), Random(0,1080,1))
	;call("fuzzysleep",1000)

	;Randomly take a break
	If $runs > 10 Then
		call("takebreak")
	EndIf

	;Resume Game
	call("fuzzyclick","left", 288, 418)
	call("fuzzysleep",3000)

	Sleep(Random(2000,3000))
EndFunc

Func getLegendaries($num)
	;Exit infinite loop
	If $num > 15 Then
		call("logmessage", "WARNING - UNABLE TO PICK UP LEGENDARY")
		call("screenshot", "legendaryfailure")
		send("{ENTER}/?{ENTER}")
		Return
	EndIf

	;Increment infinite loop counter
	$num = $num + 1

	;Pick up legendaries
	Send("{alt}")
	call("fuzzysleep",200)
	Local $coord = PixelSearch(200, 0, 1700, 800, 0xBF642F)

	If Not @error Then
		call("logmessage", "Legendary Found!")
		call("screenshot", "legendary")

		;MsgBox(0, "X and Y are:", $coord[0] & "," & $coord[1])
		MouseClick("left", $coord[0], $coord[1])
		call("fuzzysleep",2000)
		call("getLegendaries", $num)
	EndIf

	;Pick up legendaries
	Send("{alt}")
	call("fuzzysleep",200)
	Local $coord = PixelSearch(200, 0, 1700, 800, 0x00FF00)

	If Not @error Then
		call("logmessage", "Set Item Found!")
		call("screenshot", "legendary")

		;MsgBox(0, "X and Y are:", $coord[0] & "," & $coord[1])
		MouseClick("left", $coord[0], $coord[1])
		call("fuzzysleep",2000)
		call("getLegendaries", $num)
	EndIf
EndFunc

Func repair()
	Local $coord = PixelSearch(1469, 17, 1536, 104, 0xFFEB00)
	If Not @error Then
		;Log
		call("logmessage", "Repairing")

		;Move to Haedrig and repair
		call("fuzzyclick","left", 1123, 124, 5)
		call("fuzzysleep",2000)
		;Click craft
		call("fuzzyclick","left", 1004, 213, 5)
		call("fuzzysleep",2000)
		;Click repair all
		call("fuzzyclick","left", 267, 594, 5)
		call("fuzzysleep",2000)
		;Exit repair tab
		Send("{ESC}")
		call("fuzzysleep",500)

		;Move back to start
		call("fuzzyclick", "left",797, 956)
		call("fuzzysleep", 2000)

		;Wait for random amount of Time
		;;Local $waitSeconds = Random(1,35,1)
		;;call("fuzzysleep",$waitSeconds*1000)

		;Randomly wait a bit
		;;call("fuzzysleep",Random(0,5000,1))


		;Exit game
		;;Send("{ESC}")
		;;call("fuzzysleep",50)
		;;call("fuzzyclick","left", 922, 581, 5)

		;Randomly move mouse for a bit
		;;call("fuzzysleep",4000)

		;Resume Game
		;;call("fuzzyclick","left", 288, 418, 5)
		;;call("fuzzysleep",3000)

		;;call("fuzzysleep",Random(500,4500,1))
	EndIf
EndFunc

Func mousePos()
	Local $pos = MouseGetPos()
	MsgBox(0, "Mouse x,y:", $pos[0] & "," & $pos[1] & " [" & PixelGetColor($pos[0],$pos[1]) & "]")
EndFunc

Func theExit()
    Exit
EndFunc

Func checkdead($log = 1)
	;Check dead
	Local $coord = PixelSearch(600, 300, 650, 350, 0x3F3F3F)
	If Not @error Then
		Local $coord2 = PixelSearch(1300, 300, 1350, 350, 0x3F3F3F)
		If Not @error Then
			If $log = 1 Then
				call("logmessage", "Death #" & $deaths)
				call("screenshot", "death")
				$deaths = $deaths + 1
			EndIf
			Return 1
		EndIf
	EndIf

	$coord = PixelSearch(600, 300, 650, 350, 0xFFFFFF)
	If Not @error Then
		$coord2 = PixelSearch(1300, 300, 1350, 350, 0xFFFFFF)
		If Not @error Then
			If $log = 1 Then
				call("logmessage", "Death #" & $deaths)
				call("screenshot", "death")
				$deaths = $deaths + 1
			EndIf
			Return 1
		EndIf
	EndIf

	Return 0
EndFunc

Func logmessage($text)
	Local $time = @hour & ":" & @MIN & ":" & @SEC
	Local $file = FileOpen("log.txt", 1)

	; Check if file opened for writing OK
	If $file = -1 Then
		Return
	EndIf

	FileWrite($file, $time)
	FileWrite($file, " " & $text & @CRLF)

	FileClose($file)
EndFunc

Func screenshot($text)
	;$sFileName = "C:\Users\Quinn\Desktop\D3\Screenshots\" & $text & @MON & "_" & @MDAY & "_" & @YEAR & "_" & @hour & "_" & @MIN & "_" & @SEC & ".jpg"
	$sFileName = @ScriptDir & "\Screenshots\" & $text & @MON & "_" & @MDAY & "_" & @YEAR & "_" & @hour & "_" & @MIN & "_" & @SEC & ".jpg"
	call("logmessage", "Screenshotting " & $sFileName)
	_ScreenCapture_Capture($sFileName)
EndFunc

Func takebreak()
	;2.5% chance of Random 45 second Break
	Local $takebreak = Random(1,40,1)
	If $takebreak = 7 Then
		call("logmessage", "Taking 30~60 second break")
		Sleep(Random(30000,60000)) ;rest for 30~60 seconds
		call("logmessage", "Break complete")
	EndIf

	;.5% chance of Random 3~5 minute Break
	$takebreak = Random(1,200,1)
	If $takebreak = 69 Then
		call("logmessage", "Taking 3~5 minute break")
		Sleep(60000*Random(3,5,1)) ;rest for 3-5 minutes
		call("logmessage", "Break complete")
	EndIf

	;.25% chance of Random 5-7 minute Break
	$takebreak = Random(1,400,1)
	If $takebreak = 69 Then
		call("logmessage", "Taking 5~7 minute break")
		Sleep(60000*Random(5,7,1)) ;rest for 8-15 minutes
		call("logmessage", "Break complete")
	EndIf
EndFunc

Func fuzzyclick($button, $xcoord, $ycoord, $fudge = 10)
	Local $newxcoord = Random($xcoord - $fudge, $xcoord + $fudge, 1)
	Local $newycoord = Random($ycoord - $fudge, $ycoord + $fudge, 1)

	If $newxcoord < 0 Then
		$newxcoord = 0
	EndIf
	If $newxcoord > 1920 Then
		$newxcoord = 1920
	EndIf
	If $newycoord < 0 Then
		$newycoord = 0
	EndIf
	If $newycoord > 1080 Then
		$newycoord = 1080
	EndIf

	MouseClick($button, $newxcoord, $newycoord)
EndFunc

Func fuzzymove($xcoord, $ycoord, $fudge = 10)
	Local $newxcoord = Random($xcoord - $fudge, $xcoord + $fudge, 1)
	Local $newycoord = Random($ycoord - $fudge, $ycoord + $fudge, 1)

	If $newxcoord < 0 Then
		$newxcoord = 0
	EndIf
	If $newxcoord > 1920 Then
		$newxcoord = 1920
	EndIf
	If $newycoord < 0 Then
		$newycoord = 0
	EndIf
	If $newycoord > 1080 Then
		$newycoord = 1080
	EndIf

	MouseMove($newxcoord, $newycoord)
EndFunc

Func getsum($x = -1, $y = -1)
	Send("{CTRLDOWN}")
	Sleep(250)

	Local $a[2]
    $a[0] = $x
    $a[1] = $y


	;Search for Ring
	Local $fingersum = 3692926387
	Local $gray = 0x5B5B5B
    While 1
		;MsgBox(0, "debug", "PRE: "&$a[0] & ", " & $a[1])
        $b = PixelSearch($a[0] + 1, $a[1] + 1, 1920, 1080, $gray)
        If IsArray($b) Then ; If we found a matching pixel...
			;MsgBox(0, "FOUND", "FOUND: "&$b[0] & ", " & $b[1])

			If PixelCheckSum($b[0], $b[1], $b[0]+27, $b[1]+10) = $fingersum Then
                Send("{CTRLUP}")
				Return 1
            Else
				$a[0] = 0
				$a[1] = $b[1] + 1

				If $a[0] > 1600 And $a[1] > 900 Then
					;MsgBox(0,"FAILED","FAILED")
					ExitLoop
				EndIf
			EndIf
        Else
            ;MsgBox(0,":(",":(")
			ExitLoop
        EndIf
    Wend

	;amulet color: 0x767676
	;amulet checksum: 2609174597

	;Search for Amulet
	Local $amuletsum = 1085905009
	Local $amuletgray = 0x767676
	$a[0] = $x
    $a[1] = $y

    While 1
		;MsgBox(0, "debug", "PRE: "&$a[0] & ", " & $a[1])
        $b = PixelSearch($a[0] + 1, $a[1] + 1, 1920, 1080, $amuletgray)
        If IsArray($b) Then ; If we found a matching pixel...
			;MsgBox(0, "FOUND", "FOUND: "&$b[0] & ", " & $b[1])

			If PixelCheckSum($b[0], $b[1], $b[0]+27, $b[1]+10) = $amuletsum Then
                Send("{CTRLUP}")
				Return 1
            Else
				$a[0] = 0
				$a[1] = $b[1] + 1

				If $a[0] > 1600 And $a[1] > 900 Then
					;MsgBox(0,"FAILED","FAILED")
					ExitLoop
				EndIf
			EndIf
        Else
            ;MsgBox(0,":(",":(")
			ExitLoop
        EndIf
    Wend

	$demonicessencegray = 0x6F6F6F
	$demonicessencesum = 3808929274
	$a[0] = $x
    $a[1] = $y

	If $demonicEssence = 1 Then
		While 1
			;MsgBox(0, "debug", "PRE: "&$a[0] & ", " & $a[1])
			$b = PixelSearch($a[0] + 1, $a[1] + 1, 1920, 1080, $demonicessencegray)
			If IsArray($b) Then ; If we found a matching pixel...
				;MsgBox(0, "FOUND", "FOUND: "&$b[0] & ", " & $b[1])
				If PixelCheckSum($b[0], $b[1], $b[0]+27, $b[1]+10) = $demonicessencesum Then
					Send("{CTRLUP}")
					Return 1
				Else
					$a[0] = 0
					$a[1] = $b[1] + 1

					If $a[0] > 1600 And $a[1] > 900 Then
						;MsgBox(0,"FAILED","FAILED")
						ExitLoop
					EndIf
				EndIf
			Else
				;MsgBox(0,":(",":(")
				ExitLoop
			EndIf
		Wend
	EndIf


	Send("{CTRLUP}")
	Return -1
EndFunc

Func findring()
	Local $color = 0xFFFF00

	Send("{ALT}")
	call("fuzzysleep",200)

	;Find Top Rare
	Local $ringloc1 = PixelSearch(0,400,1920,780,$color)
	If IsArray($ringloc1) Then
		MouseMove($ringloc1[0], $ringloc1[1])
		;-100,-400
		If call("getsum") = 1 Then
			MouseClick("left", $ringloc1[0], $ringloc1[1])
			Return 1
		EndIf
	Else
		Return 0
	EndIf


	;Find Bot Rare
	Local $ringloc2 = PixelSearch(1920,780,0,400,$color)
	If IsArray($ringloc2) Then
		MouseMove($ringloc2[0], $ringloc2[1])
		If call("getsum") = 1 Then
			MouseClick("left", $ringloc2[0], $ringloc2[1])
			Return 1
		EndIf
	Else
		Return 0
	EndIf

	Send("{ALT}")
	call("fuzzysleep",200)

	;Find Left Rare
	Local $ringloc3 = PixelSearch(0,0, $ringloc1[0]-200,1080,$color)
	If IsArray($ringloc3) Then
		MouseMove($ringloc3[0], $ringloc3[1])
		if call("getsum") = 1 Then
			MouseClick("left", $ringloc3[0], $ringloc3[1])
			Return 1
		EndIf
	Else
		;Return 0
	EndIf

	;Find Right Rare
	Local $ringloc4 = PixelSearch(1920,0,$ringloc2[0]+200,1080,$color)
	If IsArray($ringloc4) Then
		MouseMove($ringloc4[0], $ringloc4[1])
		If call("getsum") = 1 Then
			MouseClick("left", $ringloc4[0], $ringloc4[1])
			Return 1
		EndIf
	Else
		Return 0
	EndIf
EndFunc

;Press F6 for this debug function
Func findcolor()
	Local $color = 0x6F6F6F
	Local $arr = PixelSearch(0,0,1920,1080,$color)
	If IsArray($arr) Then
		;MouseMove($arr[0],$arr[1])
		MsgBox(0,"Checksum",PixelChecksum($arr[0],$arr[1], $arr[0]+27, $arr[1]+10))
	EndIf

	;amulet color: 0x767676
	;amulet checksum: 1085905009

	;Demonic essence color: 0x808080
	;Demonic essence checksum: 1733002013
EndFunc

Func fuzzysleep($ms, $amount = 5)
	For $i=0 To $ms Step 200
		Local $x = MouseGetPos(0)
		Local $y = MouseGetPos(1)
		MouseMove(Random($x-$amount,$x+$amount,1), Random($y-$amount,$y+$amount,1))
		Sleep(100)
	Next
EndFunc